package com.wanli.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wanli.common.Result;
import com.wanli.domain.entity.Role;
import com.wanli.domain.entity.RoleMenu;
import com.wanli.domain.entity.UserRole;
import com.wanli.service.RoleMenuService;
import com.wanli.service.RoleService;
import com.wanli.service.UserRoleService;
import com.wanli.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import com.wanli.common.BaseController;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Byterain
 * @since 2023-12-06
 */
@RestController
@RequestMapping("/role")
public class RoleController extends BaseController {
    @Autowired
    UserService userService;
    @Autowired
    RoleService roleService;
    @Autowired
    RoleMenuService roleMenuService;
    @Autowired
    UserRoleService userRoleService;


    @Transactional
    @PostMapping("/perm/{roleId}")
    public Result perm(@PathVariable("roleId") Long roleId,@RequestBody Long[] menuIds){
        List<RoleMenu> roleMenusList = new ArrayList<>();
        //menuIds: 12 13 14    roleId  3
        Arrays.stream(menuIds).forEach( menuId ->{
            RoleMenu rolemenu = new RoleMenu();
            rolemenu.setMenuId(menuId);
            rolemenu.setRoleId(roleId);
            roleMenusList.add(rolemenu);
        });

        //保存关联表对象:  如果是去掉权限，就是先删除所有关联数据，然后再录入勾选权限。
        roleMenuService.remove(new QueryWrapper<RoleMenu>().eq("role_id",roleId));
        //添加新勾选权限  saveBatch() 批量保存
        roleMenuService.saveBatch(roleMenusList);
        //Redis中权限字符串也需要更新:
        userService.clearUserAuthorityInfoByRoleId(roleId);
        return Result.success("角色权限信息保存成功");
    }

    @GetMapping("/info/{id}")
    public Result info(@PathVariable("id") Long id){
        //根据角色id，查询角色信息
        Role role = roleService.getById(id);

        //根据角色id，查询该角色所能操作的菜单id
        List<RoleMenu> roleMenus = roleMenuService.list(new QueryWrapper<RoleMenu>().eq("role_id", id));
        List<Long> menuIds = roleMenus.stream().map(rm -> rm.getMenuId()).collect(Collectors.toList());
        role.setMenuIds(menuIds);
        return Result.success(role);
    }

    @Transactional
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    public Result delete(@RequestBody Long[] ids) {
        //Redis中缓存字符串更新
        Arrays.asList(ids).forEach( id ->{
            userService.clearUserAuthorityInfoByRoleId(id);
        });
        //IService removeByIds(id集合)  根据角色id删除角色信息
        roleService.removeByIds(Arrays.asList(ids));
        //删除角色和 菜单关联表 sys_role_menu
        roleMenuService.remove(new QueryWrapper<RoleMenu>().in("role_id",ids));
        //删除角色和 用户关联表 sys_user_role
        userRoleService.remove(new QueryWrapper<UserRole>().in("role_id",ids));
        return Result.success("角色信息删除成功");
    }

    //name=XXX&current=1&size=5    方法参数name:就是前端传递过来的所有角色关键词
    @PreAuthorize("hasAuthority('sys:role:list')")
    @GetMapping("/list")
    public Result list(String name){
        //分页参数: 显示页码，一页记录数 封装Page对象：
        //如果name没有值，就不进行模糊查询，如果有值，就添加模糊查询like子句
        Page<Role> roles = roleService.page(getPage(),new QueryWrapper<Role>().like(StrUtil.isNotBlank(name),"name",name));
        //Page 对象中，属性records存储是分页 角色数据，还有其它分页相关数据
        return Result.success(roles);
    }

    @GetMapping("/tree")
    public Result list(){
        List<Role> list = roleService.list();
        return Result.success(list);
    }



    @PreAuthorize("hasAuthority('sys:role:save')")
    @PostMapping("/save")
    public Result save(@RequestBody Role role){
        role.setCreated(LocalDateTime.now());
        roleService.save(role);
        return Result.success("角色信息保存成功");
    }

    @PreAuthorize("hasAuthority('sys:role:update')")
    @PostMapping("/update")
    public Result update(@RequestBody Role role){
        role.setUpdated(LocalDateTime.now());
        roleService.updateById(role);
        return Result.success("角色信息更新成功");
    }
}
